home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Commodities / AltKeyQ / AltKeyQ.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  8KB  |  269 lines

  1. /*****************************************************************************\
  2.  * AltKeyQ.c                     DICE/LATTICE C/SAS C/AZTEC C + AmigaOS 2.04 *
  3.  *                 _                                                         *
  4.  *            _   // (c)1992 by "Quarky" Dieter Temme                        *
  5.  *            \\ //                                                          *
  6.  *             \X/ --- Freeware --- ONLY AMIGA MAKES IT POSSIBLE             *
  7.  *                                                                           *
  8.  * the left ALT key with keypad numbers are assembled to ASCII values,       *
  9.  * analog to the same function found on MS-DOS PCs (don't hate me for        *
  10.  * mentioning the latter words)                                              *
  11.  *                                                                           *
  12.  * NOTE: 2.1-Includes needed!                                                *
  13. \*****************************************************************************/
  14.  
  15. #define PRGNAME "AltKeyQ"
  16. #define VERSION "1.0"
  17. #define PRGDATE "17.9.92"
  18.  
  19. #include "amigacompq.h"
  20.  
  21. #include <ctype.h>
  22. #include "stdarg.h"
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <exec/types.h>
  26. #include <clib/alib_protos.h>
  27. #include <clib/alib_stdio_protos.h>
  28. #include <clib/commodities_protos.h>
  29. #include <clib/dos_protos.h>
  30. #include <clib/exec_protos.h>
  31. #include <clib/icon_protos.h>
  32. #include <clib/intuition_protos.h>
  33. #include <clib/keymap_protos.h>
  34. #include <clib/locale_protos.h>
  35. #include <dos/dos.h>
  36. #include <exec/libraries.h>
  37. #include <exec/ports.h>
  38.  
  39. #ifdef PRAGMAS_
  40.  #include <pragmas/commodities_lib.h>
  41.  #include <pragmas/dos_lib.h>
  42.  #include <pragmas/exec_lib.h>
  43.  #include <pragmas/icon_lib.h>
  44.  #include <pragmas/intuition_lib.h>
  45.  #include <pragmas/keymap_lib.h>
  46.  #include <pragmas/locale_lib.h>
  47. #endif
  48.  
  49. #ifdef LATTICE
  50.  int CXBRK(void) { return 0; }  /* Disable Lattice CTRL-C handling */
  51.  int chkabort(void) { return 0; }
  52. #endif
  53.  
  54. #ifdef AZTEC_C
  55.  void _wb_parse(void) {    extern long Enable_Abort; Enable_Abort= FALSE; }
  56.  void _abort(void) {} /* Disable Aztec CTRL-C handling */
  57. #endif
  58.  
  59. TEXT VersionString[]= "\0$VER: " PRGNAME " " VERSION " (" PRGDATE ")";
  60.  
  61. extern struct Library *SysBase;
  62. struct Library *CxBase, *IconBase, *IntuitionBase, *LocaleBase;
  63. struct Locale *locale;
  64. struct Catalog *cat;
  65.  
  66. #define STRINGARRAY
  67. #include "AltKeyQ.h"
  68.  
  69. struct NewBroker newbroker=    /* description of commodity's details */
  70. {    5, PRGNAME, "V" VERSION " (c)1992 by \"Quarky\" Dieter Temme", NULL,
  71.     NBU_UNIQUE|NBU_NOTIFY
  72. };
  73. ULONG sendsig;                /* flag to inform main() of IEvents to send */
  74. BYTE sendsigbit= -1;        /* signal bit for flag of above */
  75. struct Task *thistask;        /* pointer to main()'s task structure */
  76. CxObj *broker;                /* commodities broker object */
  77. struct MsgPort *brokport;    /* pointer to port for commodities' messages */
  78. struct                        /* structure with information to send: */
  79. {    UBYTE value;            /*     ASCII value for the IEvent to send */
  80.     UBYTE nul;                /*     ASCII NUL byte for InvertString() */
  81. } send;
  82.  
  83. #define IECODE_LALT 0x64    /* rawkey number of left ALT key */
  84.  
  85.  
  86. /*==== clean up all before exit ====*/
  87. void ExitQ_(void)
  88. {    if (broker) DeleteCxObjAll(broker);
  89.     if (brokport)
  90.     {    struct Message *msg;
  91.         while (msg= GetMsg(brokport)) ReplyMsg(msg);
  92.         DeleteMsgPort(brokport);
  93.     }
  94.     FreeSignal(sendsigbit);
  95.     ArgArrayDone();
  96.     if (LocaleBase)
  97.     {    CloseCatalog(cat);
  98.         CloseLocale(locale);
  99.         CloseLibrary(LocaleBase);
  100.     }
  101.     if (CxBase) CloseLibrary(CxBase);
  102.     if (IconBase) CloseLibrary(IconBase);
  103.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  104. }
  105.  
  106. /*==== get catalog string localized if locale.library is open ====*/
  107. TEXT *GetCatalogStrQ_(UBYTE num)
  108. {    if (LocaleBase) return GetCatalogStr(cat, num, AppStrings[num].as_Str);
  109.     return AppStrings[num].as_Str;
  110. }
  111.  
  112. /*==== bring error text to the user ====*/
  113. void ExitError_(TEXT *format, ...)
  114. {    static struct EasyStruct easystruct=
  115.     {    sizeof(struct EasyStruct), 0, NULL, NULL, NULL
  116.     };
  117.     va_list ap;
  118.  
  119.     if (IntuitionBase)
  120.     {    DisplayBeep(NULL);
  121.         easystruct.es_TextFormat= format;
  122.         easystruct.es_GadgetFormat= GetCatalogStrQ_(MSG_ABORT_GAD);
  123.         va_start(ap, format);
  124.         EasyRequestArgs(NULL, &easystruct, NULL, &va_arg(ap, ULONG));
  125.         va_end(ap);
  126.     }
  127.  
  128.     exit(RETURN_FAIL);
  129. }
  130.  
  131. void ExitMemError_(void)
  132. {    ExitError_(GetCatalogStrQ_(MSG_NOMEMORY));
  133. }
  134.  
  135. /*==== open library ====*/
  136. struct Library *OpenLibraryQ_(TEXT *str)
  137. {    struct Library *base;
  138.  
  139.     if (!(base= OpenLibrary(str, 0)))
  140.         ExitError_(GetCatalogStrQ_(MSG_NOTFOUND), str);
  141.     return base;
  142. }
  143.  
  144. /*==== signal our task if ALT key is released ====*/
  145. GETA4TYPE_ void CollectKeys_(CxMsg *cxmsg, CxObj *cxobj)
  146. {    static TEXT keys[]= "\x0f\x1d\x1e\x1f\x2d\x2e\x2f\x3d\x3e\x3f";
  147.     static BOOL collflag;    /* TRUE if collection of keys has started */
  148.     static UBYTE value;        /* actual value of collected number keys */
  149.     struct InputEvent *ie;    /* pointer to actual input event */
  150.     TEXT *s;                /* pointer to rawkey, s-key is value of key */
  151.  
  152.     GETA4FUNC_;
  153.     ie= (struct InputEvent *)CxMsgData(cxmsg);
  154.     /* filter rawkey events */
  155.     if (ie->ie_Class == IECLASS_RAWKEY)
  156.     {    if (ie->ie_Code == (IECODE_LALT|IECODE_UP_PREFIX))
  157.         {    if (collflag)
  158.             {    /* User released left ALT key */
  159.                 send.value= value;
  160.                 Signal(thistask, sendsig);
  161.                 goto setinactive;
  162.             }
  163.         } else if (ie->ie_Qualifier&IEQUALIFIER_LALT)
  164.         {    if (s= strchr(keys, ie->ie_Code))
  165.             {    /* collect value */
  166.                 ie->ie_Code|= IECODE_UP_PREFIX;
  167.                 value= value*10+(s-keys);
  168.                 collflag= TRUE;
  169.             }
  170.         } else
  171. setinactive:
  172.         {    value= 0;
  173.             collflag= FALSE;
  174.         }
  175.     }
  176. }
  177.  
  178. /*==== main program ====*/
  179. int main(int argc, TEXT *argv[])
  180. {    ULONG cxsig;            /* signal flag of commodity message port */
  181.     ULONG sigrcvd;            /* signal flags received thru Wait() */
  182.     BOOL end= FALSE;        /* TRUE when program is to end */
  183.  
  184.     atexit(ExitQ_);
  185.  
  186.     /*- exit program if OS version not >= 2.04 -*/
  187.     if (SysBase->lib_Version < 37)
  188.     {    BPTR file;
  189.  
  190.         file= argc? Output() : Open("CON:0/0/350/30/" PRGNAME, MODE_NEWFILE);
  191.         Write(file, "Sorry, you'll need at least AmigaOS 2.04!\n", 42);
  192.         Delay(100);
  193.         Close(file);
  194.         return RETURN_FAIL;
  195.     }
  196.  
  197.     /*- open libraries -*/
  198.     IntuitionBase= OpenLibraryQ_("intuition.library");
  199.     CxBase= OpenLibraryQ_("commodities.library");
  200.     IconBase= OpenLibraryQ_("icon.library");
  201.     if (LocaleBase= OpenLibrary("locale.library", 0))
  202.     {    locale= OpenLocale(NULL);
  203.         cat= OpenCatalogA(locale, "AltKeyQ.catalog", NULL);
  204.     }
  205.  
  206.     /*- process arguments or tool types -*/
  207.     argv= ArgArrayInit(argc, argv);
  208.     newbroker.nb_Pri= (BYTE)ArgInt(argv, "CX_PRIORITY", 0);
  209.  
  210.     /*- initialize as commodity with custom object -*/
  211.     {    CxObj *custom;
  212.  
  213.         newbroker.nb_Descr= GetCatalogStrQ_(MSG_CXDESCR);
  214.         if (!(brokport= newbroker.nb_Port= CreateMsgPort())) ExitMemError_();
  215.         cxsig= 1<<brokport->mp_SigBit;
  216.         if (!(broker= CxBroker(&newbroker, 0))
  217.             || !(custom= CxCustom(CollectKeys_, 0))
  218.             || (AttachCxObj(broker, custom), CxObjError(custom)))
  219.             ExitError_(GetCatalogStrQ_(MSG_INITFAIL));
  220.         sendsig= 1<<(sendsigbit= (UBYTE)AllocSignal(-1));
  221.         thistask= FindTask(NULL);
  222.         ActivateCxObj(broker, TRUE);
  223.     }
  224.  
  225.     /*- main loop -*/
  226.     while (!end)
  227.     {    sigrcvd= Wait(sendsig|cxsig|SIGBREAKF_CTRL_C);
  228.  
  229.         /* user break received */
  230.         if (sigrcvd&SIGBREAKF_CTRL_C) end= TRUE;
  231.  
  232.         /* send collected value */
  233.         if (sigrcvd&sendsig)
  234.         {    struct InputEvent *ie;
  235.  
  236.             ie= InvertString((TEXT *)&send, NULL);
  237.             AddIEvents(ie);
  238.             FreeIEvents(ie);
  239.         }
  240.  
  241.         /* commodity server loop */
  242.         if (sigrcvd&cxsig)
  243.         {    CxMsg *cxmsg;
  244.  
  245.             while (cxmsg= (CxMsg *)GetMsg(brokport))
  246.             {    ULONG i;
  247.                 switch (i= CxMsgID(cxmsg))
  248.                 {    case CXCMD_DISABLE:
  249.                     case CXCMD_ENABLE:
  250.                         ActivateCxObj(broker, i == CXCMD_ENABLE);
  251.                         break;
  252.                     case CXCMD_KILL:
  253.                     case CXCMD_UNIQUE:
  254.                         end= TRUE;
  255.                 }
  256.                 ReplyMsg((struct Message *)cxmsg);
  257.             }
  258.         }
  259.     }
  260.  
  261.     return RETURN_OK;
  262. }
  263.  
  264. #ifdef _DCC
  265. int wbmain(struct WBStartup *wbstart)
  266. {    return main(0, (TEXT **)wbstart);
  267. }
  268. #endif
  269.